package com.gxuwz.service.impl;


import com.gxuwz.dao.LeaveDao;
import com.gxuwz.entity.Leave;
import com.gxuwz.entity.dto.LeaveDto;
import com.gxuwz.entity.vo.LeaveVo;
import com.gxuwz.entity.vo.PageVo;
import com.gxuwz.result.PageInfo;
import com.gxuwz.service.LeaveService;
import com.gxuwz.util.IDCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;


@Service
public class LeaveServiceImpl implements LeaveService {

    @Autowired
    private LeaveDao leaveDao;

    @Autowired
    private IDCodeUtil idCodeUtil;

    public PageVo getApproveLeaveList(LeaveDto leaveDto, PageInfo pageInfo) {
        PageVo pageVo = leaveDao.selectLeaveByInstID(leaveDto, leaveDto.getInstID(), pageInfo);
        List<Object> list = pageVo.getList();
        List<Object> yearLeave = new ArrayList<>();
        List<Object> termLeave = new ArrayList<>();
        List<Object> yearAndTermLeave = new ArrayList<>();
        Collections.sort(list, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                LeaveVo leaveVo1 = (LeaveVo) o1;
                LeaveVo leaveVo2 = (LeaveVo) o2;
                return Integer.parseInt(leaveVo1.getStatus()) - Integer.parseInt(leaveVo2.getStatus());
            }
        });
        if ((leaveDto.getYear() != null && !leaveDto.getYear().equals("")) && (leaveDto.getTerm() != null && !leaveDto.getTerm().equals(""))) {
            list.stream().forEach(item -> {
                LeaveVo leaveVo = (LeaveVo) item;
                Date applyTime = leaveVo.getApplyTime();
                String substring = "20" + leaveDto.getYear().substring(0, 1);
                String term = leaveDto.getTerm();
                boolean flagYear = judgeDateYear(substring, applyTime);
                boolean flagMonth = judgeDateMonth(applyTime, term);
                if (flagYear && flagMonth) {
                    yearAndTermLeave.add(item);
                }
            });
            pageVo.setList(yearAndTermLeave);
        } else if (leaveDto.getYear() != null && !leaveDto.getYear().equals("")) {
            list.stream().forEach(item -> {
                LeaveVo leaveVo = (LeaveVo) item;
                Date applyTime = leaveVo.getApplyTime();
                String substring = "20" + leaveDto.getYear().substring(0, 1);
                boolean flag = judgeDateYear(substring, applyTime);
                if (flag) {
                    yearLeave.add(item);
                }
            });
            pageVo.setList(yearLeave);
        } else if (leaveDto.getTerm() != null && !leaveDto.getTerm().equals("")) {
            list.stream().forEach(item -> {
                LeaveVo leaveVo = (LeaveVo) item;
                Date applyTime = leaveVo.getApplyTime();
                String term = leaveDto.getTerm();
                boolean flagMonth = judgeDateMonth(applyTime, term);
                if (flagMonth) {
                    termLeave.add(item);
                }
            });
            pageVo.setList(termLeave);
        }
        return pageVo;
    }

    @Override
    public LeaveVo getApproveLeaveInfo(String leaveID) {
        return leaveDao.selectLeaveByID(leaveID);
    }

    public boolean judgeDateYear(String date, Date leaveDate){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = null;
        Date endDate = null;
        try{
            startDate = simpleDateFormat.parse(date+"-09-01");
            endDate = simpleDateFormat.parse(date+"-07-01");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        if(leaveDate.compareTo(startDate) >= 0 && leaveDate.compareTo(endDate) <= 0){
            return true;
        } else {
            return false;
        }
    }

    public boolean judgeDateMonth(Date leaveDate,String term) {
        LocalDate startDate1 = LocalDate.of(leaveDate.getYear(), 9, 1);
        LocalDate endDate1 = LocalDate.of(leaveDate.getYear() + 1, 1, 31);
        LocalDate startDate2 = LocalDate.of(leaveDate.getYear(), 3, 1);
        LocalDate endDate2 = LocalDate.of(leaveDate.getYear(), 7, 1);

        LocalDate dateToCheck = LocalDate.of(leaveDate.getYear(), leaveDate.getMonth(), leaveDate.getDay());

        if (term.equals("上学期")) {
            if (dateToCheck.isAfter(startDate1) && dateToCheck.isBefore(endDate1)) {
                return true;
            } else {
                return false;
            }
        } else if (term.equals("下学期")) {
            if (dateToCheck.isAfter(startDate2) && dateToCheck.isBefore(endDate2)) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    public PageVo getLeaveList(LeaveDto leaveDto, PageInfo pageInfo,String stuID) {
        if(leaveDto == null){
            return leaveDao.selectLeaveAll(null,pageInfo,stuID);
        }
        String courseName = leaveDto.getCourseName();
//        int dayNum = leave.getDayNum();
        if( (courseName!=null && !courseName.equals(""))){
            return leaveDao.selectLeaveAll(leaveDto,pageInfo,stuID);
        } else {
            return leaveDao.selectLeaveAll(null,pageInfo,stuID);
        }
    }

    public LeaveVo getLeaveOneByLeaveID(String leaveId) {
        LeaveVo leaveVo = leaveDao.selectLeaveByLeaveID(leaveId);
        return leaveVo;
    }

    public boolean addLeaveInfo(Leave leave) {
        System.out.println(leave.toString());
        java.sql.Date date = new java.sql.Date(System.currentTimeMillis());

        String instID = leaveDao.getInstIDByStuID(leave.getStuNo());
        leave.setInstID(instID);
        leave.setApplyTime(date);
        leave.setStatus("0");

        System.out.println(leave.toString());
        int i = leaveDao.insertLeave(leave);
        boolean flag = i > 0 ? true :false;
        return flag;
    }

    public boolean deleteLeaveOne(String leaveId) {
        int i = leaveDao.deleteLeaveById(leaveId);
        boolean flag = i > 0 ? true :false;
        return flag;
    }


    public String getLeaveID() {
        return idCodeUtil.getLeaveCodeID();
    }

    @Override
    public boolean approveLeaveInfo(String leaveID, String opinion, String leaveStatus) {
        Leave leave = new Leave();
        leave.setLeaveID(leaveID);
        leave.setAuditTime(new java.sql.Date(System.currentTimeMillis()));
        leave.setOpinion(opinion);
        leave.setStatus(leaveStatus);
        int i = leaveDao.updateLeaveStatus(leave);
        boolean flag = i > 0 ? true :false;
        return flag;
    }

    @Override
    public List<LeaveVo> getExportLeaveList(LeaveDto leaveDto) {
        List<LeaveVo> list = leaveDao.selectLeaveListByInst(leaveDto, leaveDto.getInstID());
        List<LeaveVo> yearLeave = new ArrayList<>();
        List<LeaveVo> termLeave = new ArrayList<>();
        List<LeaveVo> yearAndTermLeave = new ArrayList<>();
        Collections.sort(list, new Comparator<LeaveVo>() {
            @Override
            public int compare(LeaveVo o1, LeaveVo o2) {
                LeaveVo leaveVo1 =  o1;
                LeaveVo leaveVo2 =  o2;
                return Integer.parseInt(leaveVo1.getStatus()) - Integer.parseInt(leaveVo2.getStatus());
            }
        });
        if ((leaveDto.getYear() != null && !leaveDto.getYear().equals("")) && (leaveDto.getTerm() != null && !leaveDto.getTerm().equals(""))) {
            list.stream().forEach(item -> {
                LeaveVo leaveVo =  item;
                Date applyTime = leaveVo.getApplyTime();
                String substring = "20" + leaveDto.getYear().substring(0, 1);
                String term = leaveDto.getTerm();
                boolean flagYear = judgeDateYear(substring, applyTime);
                boolean flagMonth = judgeDateMonth(applyTime, term);
                if (flagYear && flagMonth) {
                    yearAndTermLeave.add(item);
                }
            });
            return yearAndTermLeave;
        } else if (leaveDto.getYear() != null && !leaveDto.getYear().equals("")) {
            list.stream().forEach(item -> {
                LeaveVo leaveVo = item;
                Date applyTime = leaveVo.getApplyTime();
                String substring = "20" + leaveDto.getYear().substring(0, 1);
                boolean flag = judgeDateYear(substring, applyTime);
                if (flag) {
                    yearLeave.add(item);
                }
            });
            return yearLeave;
        } else if (leaveDto.getTerm() != null && !leaveDto.getTerm().equals("")) {
            list.stream().forEach(item -> {
                LeaveVo leaveVo = (LeaveVo) item;
                Date applyTime = leaveVo.getApplyTime();
                String term = leaveDto.getTerm();
                boolean flagMonth = judgeDateMonth(applyTime, term);
                if (flagMonth) {
                    termLeave.add(item);
                }
            });
            return termLeave;
        }
        return list;
    }

}
